<template>
  <div>
    <a-card>
      <a-space>
        <a-input v-model:value="listQuery.operName" placeholder="按人员搜索" allow-clear />
        <a-select
          v-model:value="listQuery.status"
          allow-clear
          :options="[
            { label: '成功', value: 1 },
            { label: '失败', value: 0 },
          ]"
          placeholder="按状态搜索"
          @change="handleFilter"
        />
        <a-date-picker
          v-model:value="listQuery.startTime"
          :show-time="{ format: 'HH:mm' }"
          valueFormat="YYYY-MM-DD HH:mm:00"
          placeholder="选择开始时间"
          allow-clear
        />
        <a-date-picker
          v-model:value="listQuery.endTime"
          :show-time="{ format: 'HH:mm' }"
          valueFormat="YYYY-MM-DD HH:mm:00"
          placeholder="选择结束时间"
          allow-clear
        />
        <a-button type="primary" :icon="h(SearchOutlined)" @click="handleFilter">搜索</a-button>
        <a-button :icon="h(UndoOutlined)" @click="handleReset">重置</a-button>
      </a-space>
    </a-card>
    <a-card class="mt-2">
      <a-space class="mb-4">
        <a-button
          v-if="checkedRowKeysRef.length && hasPermission(['operLog:delete'])"
          type="primary"
          danger
          :icon="h(DeleteOutlined)"
          @click="handleBatchDelete"
        >
          批量删除
        </a-button>
        <a-button
          v-if="pagination.total && hasPermission(['operLog:delete'])"
          type="primary"
          danger
          @click="handleTruncate"
          :icon="h(DeleteOutlined)"
        >
          清空日志
        </a-button>
      </a-space>
      <a-table
        bordered
        :columns="columns"
        :data-source="data"
        :pagination="pagination"
        :loading="tableLoading"
        :row-key="(row) => row.operId + ''"
        :row-selection="{
          preserveSelectedRowKeys: true,
          selectedRowKeys: checkedRowKeysRef,
          onChange: handleCheck,
        }"
      >
        <template #bodyCell="{ column, record }">
          <template v-if="column.dataIndex === 'status'">
            <a-tag :color="record.status ? 'success' : 'error'">
              {{ record.status ? '正常' : '异常' }}
            </a-tag>
          </template>
          <template v-else-if="column.dataIndex === 'actions'">
            <a-button size="small" type="link" @click="handleDetail(record)">详情</a-button>
          </template>
        </template>
      </a-table>
    </a-card>
    <a-modal v-model:open="showModal" title="详情" :footer="null" :width="800">
      <a-form
        ref="formRef"
        :model="form"
        style="padding-top: 20px; max-height: 80vh; overflow-y: auto"
      >
        <a-descriptions bordered :column="2" layout="vertical">
          <a-descriptions-item label="请求方式">{{ form.requestMethod }}</a-descriptions-item>
          <a-descriptions-item label="URL">{{ form.operUrl }}</a-descriptions-item>
          <a-descriptions-item label="类名">{{ form.className }}</a-descriptions-item>
          <a-descriptions-item label="方法名称">{{ form.method }}</a-descriptions-item>
          <a-descriptions-item label="IP">{{ form.ip }}</a-descriptions-item>
          <a-descriptions-item label="IP来源">{{ form.ipSource }}</a-descriptions-item>
          <a-descriptions-item label="操作状态">
            <a-tag :color="form.status ? 'success' : 'error'">
              {{ form.status ? '正常' : '异常' }}
            </a-tag>
          </a-descriptions-item>
          <a-descriptions-item label="操作人员">{{ form.operName }}</a-descriptions-item>
          <a-descriptions-item label="错误消息">{{ form.errorMsg }}</a-descriptions-item>
          <a-descriptions-item label="操作时间">{{ form.operTime }}</a-descriptions-item>
          <a-descriptions-item label="请求参数">
            <pre style="max-width: 340px; overflow-x: auto">{{ form.operParam }}</pre>
          </a-descriptions-item>
          <a-descriptions-item label="返回参数">
            <pre style="max-width: 340px; overflow-x: auto">{{ form.jsonResult }}</pre>
          </a-descriptions-item>
        </a-descriptions>
      </a-form>
    </a-modal>
  </div>
</template>

<script setup lang="tsx">
  import { h, onMounted, reactive, ref } from 'vue';
  import OperLogApi from '@/api/OperLogApi';
  import { usePermission } from '@/hooks/usePermission';
  import { DeleteOutlined, SearchOutlined, UndoOutlined } from '@ant-design/icons-vue';
  import { message, Modal } from 'ant-design-vue';
  import { resetReactive } from '@/utils';

  const { hasPermission } = usePermission();

  let columns = [
    { title: '日志编号', dataIndex: 'operId', width: 120 },
    { title: '请求方式', width: 120, dataIndex: 'requestMethod' },
    {
      title: 'URL',
      dataIndex: 'operUrl',
      ellipsis: {
        tooltip: true,
      },
    },
    { title: 'IP来源', dataIndex: 'ipSource', width: 150 },
    { title: '操作人员', dataIndex: 'operName', width: 150 },
    {
      title: '操作状态',
      dataIndex: 'status',
      align: 'center',
      width: 100,
    },
    { title: '操作时间', dataIndex: 'operTime', width: 180 },
    {
      title: '操作',
      dataIndex: 'actions',
      align: 'center',
      width: 100,
    },
  ];
  let data = ref([]);
  const pagination = reactive({
    current: 1,
    pageSize: 10,
    total: 0,
    onChange: (current, pageSize) => {
      pagination.current = current;
      pagination.pageSize = pageSize;
      getList();
    },
  });
  onMounted(() => {
    getList();
  });

  const listQuery = reactive<any>({});

  const tableLoading = ref(false);

  function getList() {
    tableLoading.value = true;
    OperLogApi.page({ index: pagination.current, size: pagination.pageSize, ...listQuery })
      .then((res) => {
        data.value = res.data;
        pagination.total = res.total;
      })
      .finally(() => (tableLoading.value = false));
  }

  function handleFilter() {
    pagination.current = 1;
    getList();
  }

  const showModal = ref(false);
  const formRef = ref();
  let form = reactive<OperLog>({});

  function handleDetail(row) {
    showModal.value = true;
    Object.assign(form, row);
  }

  function handleReset() {
    resetReactive(listQuery);
    handleFilter();
  }

  const checkedRowKeysRef = ref([]);

  function handleCheck(rowKeys: string[]) {
    checkedRowKeysRef.value = rowKeys;
  }

  function handleBatchDelete() {
    Modal.confirm({
      title: '提示',
      content: `确定删除所选的${checkedRowKeysRef.value.length}条数据吗?`,
      okText: '确定',
      cancelText: '取消',
      onOk: () => {
        OperLogApi.delete(checkedRowKeysRef.value).then(() => {
          message.success('操作成功！');
          checkedRowKeysRef.value = [];
          handleFilter();
        });
      },
      onCancel: () => {},
    });
  }

  function handleTruncate() {
    Modal.confirm({
      title: '提示',
      content: `确定清空所有日志数据吗?`,
      okText: '确定',
      cancelText: '取消',
      onOk: () => {
        OperLogApi.truncate().then(() => {
          message.success('操作成功！');
          handleFilter();
        });
      },
      onCancel: () => {},
    });
  }
</script>

<style scoped></style>
